from socket import *
from multiprocessing import Process
from online_dict_db import Mysql


# 网络服务搭建类
class TcpServer:
    def __init__(self, host="", port=0):
        self.host = host
        self.port = port
        self.addr = (host, port)
        self.sock = self._create_socket()

    def _create_socket(self):
        sock = socket()
        sock.bind(self.addr)
        return sock

    def _start_server(self):
        self.sock.listen(5)
        print("The listen port is ", self.port)
        while True:
            try:
                connfd, addr = self.sock.accept()
                print("Connect from ", addr)
            except KeyboardInterrupt:
                self.sock.close()
                return
            process = CreateProcess(connfd)
            process.start()


# 负责创建子进程
class CreateProcess(Process):
    def __init__(self, connfd):
        self.connfd = connfd
        self.__handle = Handle(connfd)
        super().__init__(daemon=True)  # 子进程随父进程结束而结束

    def run(self):
        db.cursor()  # 因为各个子进程不可公用游标以防互相干扰，所以不可在父进程中创建而应在子进程中创建
        self.__handle.do_request()
        db.cur.close()
        self.connfd.close()


# 具体处理
class Handle:
    def __init__(self, connfd):
        self.connfd = connfd
        self.username = None

    def do_request(self):
        while True:
            request = self.connfd.recv(1024).decode()
            # print(request.decode())
            tmp = request.split("\t")
            if not request or tmp[0] == "EXIT":
                break
            elif tmp[0] == "ENROL":
                # print(b"test")
                self.enrol_infor(tmp[1], tmp[2])
            elif tmp[0] == "LOGIN":
                self.login_user(tmp[1], tmp[2])
            elif tmp[0] == "Query":

                self.query_words(tmp[1])
            elif tmp[0] == "History":
                self.history_infor()

    # 处理注册
    def enrol_infor(self, name, password):
        """
        将前端传来的用户名与数据库用户名作对比，若数据库不存在该用户名则允许注册返回OK。否则返回False
        :param name:
        :param password:
        :return:
        """
        result = db.enrol_infor(name, password)
        if result:
            self.connfd.send(b"OK")
        else:
            self.connfd.send(b"False")

    # 处理登录
    def login_user(self, name, password):
        if db.validate_enter(name, password):
            self.username = name
            self.connfd.send(b"OK")
        else:
            self.connfd.send(b"False")

    # 处理查询单词
    def query_words(self, word):
        mean = db.select_words(self.username, word)
        if mean:
            response = "T\t" + mean
            self.connfd.send(response.encode())
        else:
            self.connfd.send(b"F")

    # 查询历史记录
    def history_infor(self):
        # ((name,word,time)...)  ()
        rows = db.search_history(self.username)
        if rows:
            response = "T\t"  # "T\tname,word,time;...."
            for row in rows:
                # "T\tname,word,time;...."
                data = "%s,%s,%s;" % row
                response += data
            self.connfd.send(response.encode())
        else:
            self.connfd.send(b"F")


if __name__ == '__main__':
    db = Mysql()
    tcp = TcpServer("0.0.0.0", 8000)
    tcp._start_server()
    db.close()
